﻿using Ces.Entity;
using DevExpress.Utils;
using DevExpress.Utils.Design;
using DevExpress.Utils.Win;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraEditors.Popup;
using DevExpress.XtraEditors.TextEditController.Win32;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Editors;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraLayout;
using DevExpress.XtraTreeList.Data;
using MesProjectWinform.Entity.Request;
using MesProjectWinform.Helper;
using MesProjectWinform.Public;
using MesProjectWinform.Public.Common;
using MesProjectWinform.WareHouse.Entity;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MesProjectWinform.WareHouse.Form.仓库定义
{
    public partial class Form_WareHouseAdd : DevExpress.XtraEditors.DirectXForm
    {
        public bool UpdateType = false;
        
        // 使用WareHouses类来接收数据
        public WareHouses CurrentWareHouse { get; set; }
        
        public Form_WareHouseAdd()
        {
            InitializeComponent();
            
            // 窗体显示后事件
            this.Shown += Form_WareHouseAdd_Shown;
        }

        private Dictionary<string, string> listEmpID = new Dictionary<string, string>();

        private async void WareHouseAddForm_Load(object sender, EventArgs e)
        {
            try
            {
                // 显示等待光标
                Cursor = Cursors.WaitCursor;
                
                // 加载仓库类型下拉框数据
                lookUpWHType();
                
                if (UpdateType)
                {
                    // 新增模式
                    this.Text = "新增仓库";
                    BtnAdd.Text = "新增";
                    
                    // 直接异步获取编码并设置到文本框 - 不使用Task.Run
                    string code = await GetCode();
                    WareHouseId.Text = code;
                }
                else
                {
                    // 修改模式
                    this.Text = "修改仓库";
                    BtnAdd.Text = "保存";
                    
                    // 绑定传入的数据到控件
                    if (CurrentWareHouse != null)
                    {
                        // 填充表单控件
                        WareHouseId.Text = CurrentWareHouse.Warehouseid;
                        WareHouseName.Text = CurrentWareHouse.Warehousename;
                        Address.Text = CurrentWareHouse.Address;
                        Memo.Text = CurrentWareHouse.Memo;
                        
                        // 设置仓库管理员信息
                        textEdit2.Text = CurrentWareHouse.Warehouseempid;
                        
                        // 如果有员工ID数据，解析并存入listEmpID
                        if (!string.IsNullOrEmpty(CurrentWareHouse.Warehouseempid))
                        {
                            // 解析员工文本并存储到listEmpID中
                            listEmpID = ParseEmployeeText(CurrentWareHouse.Warehouseempid);
                        }
                        
                        // 设置仓库类型
                        LUType.EditValue = CurrentWareHouse.WHTypeId;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("加载窗体时发生错误：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                // 恢复光标
                Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// 窗体显示后事件 - 确保编码显示
        /// </summary>
        private async void Form_WareHouseAdd_Shown(object sender, EventArgs e)
        {
            // 仅在新增模式且编码为空时重新获取
            if (UpdateType && string.IsNullOrEmpty(WareHouseId.Text))
            {
                try
                {
                    System.Diagnostics.Debug.WriteLine("窗体显示后，编码为空，重新获取...");
                    string code = await GetCode();
                    WareHouseId.Text = code;
                    System.Diagnostics.Debug.WriteLine($"重新获取的编码: {code}");
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine($"窗体显示后获取编码异常: {ex.Message}");
                }
            }
        }

        private async Task<string> GetCode()
        {
            try
            {
                // 显示等待光标
                Cursor = Cursors.WaitCursor;
                
                // 添加调试输出
                
                string codePrefix = DataConverHelper.GetPrefix(CodeType.WareHouse);
                
                // 首先尝试直接生成一个新编码作为备选
                string fallbackCode = DataConverHelper.GenerateCode(CodeType.WareHouse);
                
                try
                {
                    // 调用API获取最新编码
                    string apiUrl = "WareHouse/BasicInfo/GetCode?Type=" + codePrefix;
                    
                    string json = await HttpClientHelper.RequestUrl(RequestType.Get, apiUrl, null);
                    
                    if (string.IsNullOrEmpty(json))
                    {
                        return fallbackCode;
                    }
                    
                    ApiResult<TypeCodeModel> typeModel = JsonConvert.DeserializeObject<ApiResult<TypeCodeModel>>(json);
                    
                    if (typeModel == null)
                    {
                        return fallbackCode;
                    }
                    
                    
                    if (typeModel.Data == null)
                    {
                        return fallbackCode;
                    }
                    
                    string lastCode = typeModel.Data.Code;
                    
                    if (string.IsNullOrEmpty(lastCode))
                    {
                        return fallbackCode;
                    }

                    // 获取数字部分（后五位或全部，如果不足五位）
                    string numberPart;
                    string prefixPart;
                    
                    // 提取数字部分和前缀部分
                    if (lastCode.Length >= 5)
                    {
                        // 如果编码长度超过5位，提取最后6位作为数字部分，其余作为前缀
                        numberPart = lastCode.Substring(lastCode.Length -5);
                        prefixPart = lastCode.Substring(0, lastCode.Length - 5);
                    }
                    else
                    {
                        // 如果编码长度不足5位，就用整个编码作为数字部分，前缀为空
                        numberPart = lastCode;
                        prefixPart = "";
                    }
                    
                    // 尝试解析为数字并自增1
                    if (int.TryParse(numberPart, out int lastNumber))
                    {
                        // 获取当前日期字符串
                        string currentDateStr = DateTime.Now.ToString("yyMMdd");
                        string dateInPrefix = "";
                        
                        // 检查前缀中是否包含日期信息
                        if (prefixPart.Length >= 8 && prefixPart.StartsWith(codePrefix))
                        {
                            dateInPrefix = prefixPart.Substring(2, 6);
                        }
                        
                        // 如果前缀中的日期与当前日期不同，或者前缀不合规范，则重置编号并使用新日期
                        if (string.IsNullOrEmpty(prefixPart) || !prefixPart.StartsWith(codePrefix) || 
                            (dateInPrefix != currentDateStr && !string.IsNullOrEmpty(dateInPrefix)))
                        {
                            // 新的一天，编号从1开始
                            prefixPart = codePrefix + currentDateStr;
                            lastNumber = 1; // 重置为1
                        }
                        else
                        {
                            // 同一天，编号递增
                            lastNumber++;
                        }
                        
                        // 数字部分解析成功，确保是6位数（前面补0）
                        string sixDigitNumber = lastNumber.ToString("D5");
                        
                        // 组合新编码
                        string newCode = prefixPart + sixDigitNumber;
                        return newCode;
                    }
                    else
                    {
                        return fallbackCode;
                    }
                }
                catch (Exception ex)
                {
                    return fallbackCode;
                }
            }
            finally
            {
                // 恢复光标
                Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// 下拉框类型仓库填充
        /// </summary>
        public async void lookUpWHType()
        {
            string json = await HttpClientHelper.RequestUrl(RequestType.Get, "WareHouse/BasicInfo/GetWareHouseType", null);// await APIClient.CallApiAsync("api/BasicInfo/GetWareHouseType", HttpMethod.GET);
            // 假设返回的是JSON数组，可以用DataTable显示
            //var items = JsonConvert.DeserializeObject<ApiResult<WareHouseType>>(json);
            //dt = DataConverHelper.ToDataTable(model.Data);

            ApiResult<List<WareHouseType>> TypeModel = JsonConvert.DeserializeObject<ApiResult<List<WareHouseType>>>(json);

            LUType.EditValue = "WHTypeId";
            LUType.Properties.ValueMember = "WHTypeId";
            LUType.Properties.DisplayMember = "WHTypeName";
            LUType.Properties.DataSource = TypeModel.Data;

            //列格式设置
            LUType.Properties.Columns[0].FormatString = "000000";

            //选择第一项
            LUType.ItemIndex = 0;

        }

        /// <summary>
        /// 关闭页面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }


        /// <summary>
        /// 新增或修改仓库信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void BtnAdd_Click(object sender, EventArgs e)
        {
            // 防止重复点击
            BtnAdd.Enabled = false;
            BtnClose.Enabled = false;
            
            // 记录操作开始时间，用于防止重复提交
            string requestId = Guid.NewGuid().ToString();
            
            try
            {
                // 显示等待光标
                Cursor = Cursors.WaitCursor;
                
                // 检查必填字段是否有值
                string errorMessage = Check();
                if (!string.IsNullOrEmpty(errorMessage))
                {
                    MessageBox.Show(errorMessage, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                
                // 验证编码是否已被占用（并发检查）
                bool isCodeAvailable = await CheckCodeAvailability(WareHouseId.Text.Trim());
                if (!isCodeAvailable && UpdateType) // 只在新增模式下检查
                {
                    MessageBox.Show("仓库编码已被占用，请刷新后重试", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                
                WareHouses model = new WareHouses();
                
                // 如果是修改模式，使用传入对象的ID和创建信息
                if (!UpdateType && CurrentWareHouse != null)
                {
                    model.WHId = CurrentWareHouse.WHId;
                    model.CreatedBy = CurrentWareHouse.CreatedBy;
                    model.CreatedTime = CurrentWareHouse.CreatedTime;
                    model.UpdatedBy = string.IsNullOrEmpty(CurrentWareHouse.EMPID) ? "00" : CurrentWareHouse.EMPID;
                    model.UpdatedTime = DateTime.Now;
                    model.Warehouseid = CurrentWareHouse.Warehouseid; // 保持原编码，防止修改
                }
                else
                {
                    // 新增模式，初始化创建信息
                    model.WHId = 0;
                    model.CreatedTime = DateTime.Now;
                    model.CreatedBy = "00";
                    model.UpdatedBy = model.CreatedBy;
                    model.UpdatedTime = DateTime.Now;
                    model.Warehouseid = WareHouseId.Text.Trim();
                }
                
                // 设置基本信息
                model.Warehousename = WareHouseName.Text.Trim();
                model.WHTypeId = LUType.EditValue?.ToString() ?? "";
                model.Address = Address.Text.Trim();
                model.Memo = Memo.Text.Trim();
                model.IsEnable = true;
                // 处理员工ID
                // 如果listEmpID为空但textEdit2有值，尝试解析textEdit2的值
                if (listEmpID.Count == 0 && !string.IsNullOrEmpty(textEdit2.Text))
                {
                    listEmpID = ParseEmployeeText(textEdit2.Text);
                }
                
                // 生成员工ID字符串
                string empNames = listEmpID.Count > 0 ? string.Join(", ", listEmpID.Keys) : textEdit2.Text.Trim();
                model.Warehouseempid = empNames;
                
                // 将对象序列化为JSON
                string postData = JsonConvert.SerializeObject(model);
                
                // 添加请求ID，用于防止重复提交
                Dictionary<string, string> headers = new Dictionary<string, string>
                {
                    { "X-Request-ID", requestId },
                    { "X-Client-Timestamp", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") }
                };
                
                int maxRetries = 3;
                int retryCount = 0;
                bool success = false;
                
                while (!success && retryCount < maxRetries)
                {
                    try
                    {
                        // 根据操作类型选择API
                        string url = UpdateType ? "WareHouse/WareHouse/AddWareHouse" : "WareHouse/WareHouse/UpdateWareHouse";
                        
                        // 使用带自定义头的请求方法
                        string json = await HttpClientHelper.RequestUrl(RequestType.Post, url, postData); 
                        ApiResult<int> baseModel = JsonConvert.DeserializeObject<ApiResult<int>>(json);
                        
                        if (baseModel.Code == ApiEnums.Success)
                        {
                            // 更新编码记录
                            await UpdateCode();
                            
                            string message = UpdateType ? "添加成功" : "修改成功";
                            MessageBox.Show(message, "操作成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            this.DialogResult = DialogResult.OK;
                            
                            // 标记成功
                            success = true;
                            
                            // 关闭窗口
                            this.Close();
                        }
                        else
                        {
                            // 检查是否是因为并发冲突导致的失败
                            if (baseModel.Code == ApiEnums.Error)
                            {
                                retryCount++;
                                if (retryCount < maxRetries)
                                {
                                    // 等待一段时间后重试
                                    await Task.Delay(1000 * retryCount); // 逐次增加等待时间
                                    continue;
                                }
                            }
                            
                            MessageBox.Show(baseModel.Message, "操作失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        retryCount++;
                        if (retryCount >= maxRetries)
                        {
                            MessageBox.Show("保存数据时发生错误：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            break;
                        }
                        
                        // 等待一段时间后重试
                        await Task.Delay(1000 * retryCount);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("保存数据时发生错误：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                // 恢复按钮状态
                BtnAdd.Enabled = true;
                BtnClose.Enabled = true;
                
                // 恢复光标
                Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// 检查仓库编码是否可用
        /// </summary>
        /// <param name="code">待检查的编码</param>
        /// <returns>编码是否可用</returns>
        private async Task<bool> CheckCodeAvailability(string code)
        {
            try
            {
                // 调用API检查编码是否可用
                string url = $"WareHouse/WareHouse/GetWareHouseID?WareHouseID={Uri.EscapeDataString(code)}";
                string json = await HttpClientHelper.RequestUrl(RequestType.Get, url, null);
                ApiResult<int> result = JsonConvert.DeserializeObject<ApiResult<int>>(json);
                
                // 返回true表示编码可用，false表示编码已被占用
                return  result.Code == ApiEnums.Success ;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"检查编码可用性时发生异常: {ex.Message}");
                // 出现异常时，假定编码可用，让后续流程继续（后端会再次检查）
                return true;
            }
        }

        /// <summary>
        /// 更新编码记录
        /// </summary>
        public async Task UpdateCode()
        {
            try
            {
                // 根据操作类型选择API
                string url = "WareHouse/BasicInfo/UpdateCode";
                TypeCodeModel model = new TypeCodeModel();
                model.Code = WareHouseId.Text;
                model.CodeType = DataConverHelper.GetPrefix(CodeType.WareHouse);
                model.CodeTypeName = "仓库";
                string postData = JsonConvert.SerializeObject(model);
                
                // 设置重试次数
                int maxRetries = 3;
                int retryCount = 0;
                bool success = false;
                
                while (!success && retryCount < maxRetries)
                {
                    try
                    {
                        string json = await HttpClientHelper.RequestUrl(RequestType.Put, url, postData);
                        ApiResult<int> baseModel = JsonConvert.DeserializeObject<ApiResult<int>>(json);
                        
                        if (baseModel != null && baseModel.Code == ApiEnums.Success)
                        {
                            success = true;
                            return;
                        }
                        
                        // 如果失败，尝试重试
                        retryCount++;
                        if (retryCount < maxRetries)
                        {
                            await Task.Delay(1000 * retryCount);
                        }
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debug.WriteLine($"更新编码记录时发生异常: {ex.Message}");
                        retryCount++;
                        if (retryCount < maxRetries)
                        {
                            await Task.Delay(1000 * retryCount);
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"更新编码记录失败: {ex.Message}");
                // 这里选择不抛出异常，因为即使编码记录更新失败，主业务流程已经完成
            }
        }

        /// <summary>
        /// 处理从CheckEmpForm接收到的员工数据
        /// </summary>
        /// <param name="empData">员工数据字典</param>
        private void HandleEmpDataReceived(Dictionary<string, string> empData)
        {
            try
            {
                // 清空原有数据
                listEmpID.Clear();
                
                // 复制收到的员工数据
                if (empData != null && empData.Count > 0)
                {
                    foreach (var item in empData)
                    {
                        listEmpID[item.Key] = item.Value;
                    }
                    
                    // 更新界面显示
                    string empNames = DataConverHelper.ToIdNameString(listEmpID);
                    textEdit2.Text = empNames;
                    
                    System.Diagnostics.Debug.WriteLine($"接收到 {listEmpID.Count} 个员工ID");
                }
                else
                {
                    // 如果没有选择员工，清空文本框
                    textEdit2.Text = string.Empty;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("处理员工数据时发生错误：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 选择
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void simpleButton2_Click(object sender, EventArgs e)
        {
            Form_CheckEmp frm = new Form_CheckEmp();

            // 订阅事件以接收员工数据
            frm.OnEmpDataSelected += new EmpDataTransferHandler(HandleEmpDataReceived);
            
            // 如果textEdit2有值，解析并预选对应的员工
            if (!string.IsNullOrEmpty(textEdit2.Text))
            {
                Dictionary<string, string> preSelectedEmps = ParseEmployeeText(textEdit2.Text);
                if (preSelectedEmps.Count > 0)
                {
                    frm.SetPreSelectedEmployees(preSelectedEmps);
                }
            }

            // 显示窗体
            frm.ShowDialog();
        }
        
        /// <summary>
        /// 解析员工文本，支持多种格式：
        /// 1. "(Id)Name, (Id)Name" - 带括号的ID和名称
        /// 2. "Id, Id" - 仅ID
        /// 3. "Id Name, Id Name" - ID和名称之间有空格
        /// </summary>
        /// <param name="employeeText">员工文本</param>
        /// <returns>员工ID和名称字典</returns>
        private Dictionary<string, string> ParseEmployeeText(string employeeText)
        {
            Dictionary<string, string> result = new Dictionary<string, string>();
            
            if (string.IsNullOrEmpty(employeeText))
                return result;
            
            try
            {
                // 分割多个员工
                string[] employees = employeeText.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                
                foreach (string emp in employees)
                {
                    string trimmedEmp = emp.Trim();
                    if (string.IsNullOrEmpty(trimmedEmp))
                        continue;
                    
                    // 尝试提取ID和名称
                    string empId = string.Empty;
                    string empName = string.Empty;
                    
                    // 检查是否包含括号格式 "(Id)Name"
                    int startBracket = trimmedEmp.IndexOf('(');
                    int endBracket = trimmedEmp.IndexOf(')');
                    
                    if (startBracket >= 0 && endBracket > startBracket)
                    {
                        // 提取括号中的ID
                        empId = trimmedEmp.Substring(startBracket + 1, endBracket - startBracket - 1).Trim();
                        
                        // 如果括号后面有名称，提取名称
                        if (endBracket + 1 < trimmedEmp.Length)
                        {
                            empName = trimmedEmp.Substring(endBracket + 1).Trim();
                        }
                    }
                    else
                    {
                        // 检查是否包含空格（可能是"Id Name"格式）
                        int spaceIndex = trimmedEmp.IndexOf(' ');
                        
                        if (spaceIndex > 0)
                        {
                            // 假设空格前是ID，空格后是名称
                            empId = trimmedEmp.Substring(0, spaceIndex).Trim();
                            empName = trimmedEmp.Substring(spaceIndex + 1).Trim();
                        }
                        else
                        {
                            // 如果没有空格，假设整个字符串是ID
                            empId = trimmedEmp;
                        }
                    }
                    
                    // 添加到结果字典中
                    if (!string.IsNullOrEmpty(empId) && !result.ContainsKey(empId))
                    {
                        result.Add(empId, empName);
                    }
                }
                
                // 输出日志，方便调试
                if (result.Count > 0)
                {
                    System.Diagnostics.Debug.WriteLine($"解析到 {result.Count} 个员工ID");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("解析员工信息时出错: " + ex.Message, "解析错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            
            return result;
        }

        /// <summary>
        /// 检查是否有未填数据
        /// </summary>
        public string Check()
        {
            List<string> emptyFields = new List<string>();
            
            // 检查仓库编号
            if (string.IsNullOrWhiteSpace(WareHouseId.Text))
            {
                emptyFields.Add("仓库编号");
            }
            
            // 检查仓库名称
            if (string.IsNullOrWhiteSpace(WareHouseName.Text))
            {
                emptyFields.Add("仓库名称");
            }
            
            // 检查仓库类型
            if (LUType.EditValue == null || string.IsNullOrWhiteSpace(LUType.EditValue.ToString()))
            {
                emptyFields.Add("仓库类型");
            }
            
            // 检查仓库管理员
            if (string.IsNullOrWhiteSpace(textEdit2.Text))
            {
                emptyFields.Add("仓库管理员");
            }
            
            //// 检查地址
            //if (string.IsNullOrWhiteSpace(Address.Text))
            //{
            //    emptyFields.Add("仓库地址");
            //}
            
            // 如果有空字段，返回错误消息
            if (emptyFields.Count > 0)
            {
                return $"添加失败，以下字段不能为空：{string.Join("、", emptyFields)}";
            }
            
            // 所有字段都已填写
            return string.Empty;
        }
    }
}